package com.woupla.rdv;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.inject.Inject;
import javax.inject.Named;

import org.jboss.solder.logging.Logger;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.DateTimeZone;
import org.primefaces.event.DateSelectEvent;
import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.ScheduleEntryResizeEvent;
import org.primefaces.event.ScheduleEntrySelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.LazyScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

import com.woupla.model.Companyproduit;
import com.woupla.model.Planing;
import com.woupla.model.User;

@Named
@ViewScoped
public class RdvPlaningMbean implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = -33831375510313429L;

	@Inject
	private Logger log;

	@Inject
	private RdvEJB rdvEJB;

	private ScheduleModel eventModel;

	private ScheduleEvent event = new DefaultScheduleEvent();

	private String theme;

	public RdvPlaningMbean() {
		eventModel = new LazyScheduleModel() {

			/**
				 * 
				 */
			private static final long serialVersionUID = 1L;
			private String tempsTest = "111111111111";
			private int positionDeb;
			Date dateStart = new Date();
			Date dateEnd = new Date();

			@Override
			public void loadEvents(Date start, Date end) {
				Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
				// plus 1 jour sur la semaine car le calendrier envoi dimanche
				// comme 1er jour de semaine
				calendar.setTime(start);
				int semDeb = calendar.get(Calendar.WEEK_OF_YEAR) + 1;
				calendar.setTime(end);
				int semFin = calendar.get(Calendar.WEEK_OF_YEAR);
				List<Planing> planings = rdvEJB.findPlaningUser(new User(),
						semDeb, semFin);
				planings.add(new Planing());
				for (Planing planing : planings) {
					if (planing.getPlaningPK() == null)
						break;
					StringBuffer lundi = new StringBuffer();
					lundi.append(planing.getLundi());
					addEventsDay(DateTimeConstants.MONDAY, semDeb, lundi);
					StringBuffer mardi = new StringBuffer();
					mardi.append(planing.getMardi());
					addEventsDay(DateTimeConstants.TUESDAY, semDeb, mardi);
					StringBuffer mercredi = new StringBuffer();
					mercredi.append(planing.getMercredi());
					addEventsDay(DateTimeConstants.WEDNESDAY, semDeb, mercredi);
					StringBuffer jeudi = new StringBuffer();
					jeudi.append(planing.getJeudi());
					addEventsDay(DateTimeConstants.THURSDAY, semDeb, jeudi);
					StringBuffer vendredi = new StringBuffer();
					vendredi.append(planing.getVendredi());
					addEventsDay(DateTimeConstants.FRIDAY, semDeb, vendredi);
					StringBuffer samedi = new StringBuffer();
					samedi.append(planing.getSamedi());
					addEventsDay(DateTimeConstants.SATURDAY, semDeb, samedi);
					StringBuffer dimanche = new StringBuffer();
					dimanche.append(planing.getDimanche());
					addEventsDay(DateTimeConstants.SUNDAY, semDeb, dimanche);

				}

			}

			public void addEventsDay(int dayOfWeek, int numWeek, StringBuffer planingDay) {
				positionDeb = 0;
				int positionEncours = 0;
				while (positionEncours+tempsTest.length() < 289) {
					positionDeb = planingDay.indexOf(tempsTest);
					planingDay = planingDay.delete(0, positionDeb + tempsTest.length());
					dateStart = getDateStart(positionDeb + positionEncours, dayOfWeek, numWeek);
					dateEnd = getDateEnd(dateStart, tempsTest.length());
					eventModel.addEvent(new DefaultScheduleEvent("Disponible !!!!! ", dateStart, dateEnd));
					positionEncours = positionDeb + positionEncours + tempsTest.length();
				}
			}

			public Date getDateStart(int slotStart, int dayOfWeek, int numWeek) {
				DateTime dateTime = new DateTime();
				dateTime = dateTime.withWeekOfWeekyear(numWeek);
				dateTime = dateTime.withDayOfWeek(dayOfWeek);
				Double hour = Math.floor((slotStart * 5) / 60);
				dateTime = dateTime.withHourOfDay(hour.intValue());
				int min = ((slotStart * 5) % 60);
				dateTime = dateTime.withMinuteOfHour(min);
				dateTime =dateTime.withSecondOfMinute(0);
				dateTime = dateTime.withMillisOfSecond(0);
				dateTime = dateTime.withZoneRetainFields(DateTimeZone.UTC);
	
				return dateTime.toDate();
			}

			public Date getDateEnd(Date dateStart, int nbSlot) {
				DateTime dateTime = new DateTime(dateStart, DateTimeZone.UTC);
				dateTime =dateTime.plusMinutes(nbSlot*5);
				return dateTime.toDate();

			}
		};

	}

	public Date getRandomDate(Date base) {
		Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
		date.setTime(base);
		date.add(Calendar.DATE, ((int) (Math.random() * 30)) + 1); // set random
																	// day of
																	// month

		return date.getTime();
	}

	public Date getInitialDate() {
		Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
		calendar.set(calendar.get(Calendar.YEAR), Calendar.FEBRUARY, calendar.get(Calendar.DATE), 0, 0, 0);

		return calendar.getTime();
	}

	public ScheduleModel getEventModel() {
		return eventModel;
	}

	public ScheduleEvent getEvent() {
		return event;
	}

	public void setEvent(ScheduleEvent event) {
		this.event = event;
	}

	public void takeRDV(ActionEvent actionEvent) {
		if (event.getId() == null) {
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event error", "No event selected");
			addMessage(message);
		}
		else{
			User employee = new User();
			employee.setId(60);
			Companyproduit produit = new Companyproduit(1,(long) 1,1);
			DateTime start = new DateTime(event.getStartDate(), DateTimeZone.UTC);
			start = start.withZoneRetainFields(DateTimeZone.forID("Europe/Paris"));
			DateTime end = new DateTime(event.getEndDate(), DateTimeZone.UTC);
			end = end.withZoneRetainFields(DateTimeZone.forID("Europe/Paris"));
			rdvEJB.addRdv(employee, employee,start.toDate() , end.toDate(), produit);
			eventModel.deleteEvent(event);
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event ok", "Rdv take");
			addMessage(message);
		}

		event = new DefaultScheduleEvent();
	}

	public void addEvent(ActionEvent actionEvent) {
		if (event.getId() == null) {
			eventModel.addEvent(event);
		}
		else {
			eventModel.updateEvent(event);
		}

		event = new DefaultScheduleEvent();
	}

	public void onEventSelect(ScheduleEntrySelectEvent selectEvent) {
		event = selectEvent.getScheduleEvent();
	}

	public void onDateSelect(DateSelectEvent selectEvent) {
		event = new DefaultScheduleEvent(Math.random() + "",
				selectEvent.getDate(), selectEvent.getDate());
	}

	public void onEventMove(ScheduleEntryMoveEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Event moved", "Day delta:" + event.getDayDelta()
						+ ", Minute delta:" + event.getMinuteDelta());

		addMessage(message);
	}

	public void onEventResize(ScheduleEntryResizeEvent event) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Event resized", "Day delta:" + event.getDayDelta()
						+ ", Minute delta:" + event.getMinuteDelta());

		addMessage(message);
	}

	private void addMessage(FacesMessage message) {
		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public String getTheme() {
		return theme;
	}

	public void setTheme(String theme) {
		this.theme = theme;
	}
}
